package com.fido.kingkongview.indicator

import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.fido.kingkongview.KingKongStyle
import com.fido.kingkongview.interf.OnKingKongScrollListener
import com.fido.kingkongview.utils.dp
import com.fido.kingkongview.utils.format
import com.fido.kingkongview.utils.margin
import com.fido.kingkongview.utils.scrollPercent

/**
 * @author: FiDo
 * @date: 2024/7/26
 * @des:
 */
class KingKongIndicator @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : View(context, attrs) {

    private var paint:Paint?=null
    private val mIndicatorRectF = RectF()
    private val mThumbRectF = RectF()
    private val mSmallThumbRectF = RectF()  // style == FakeAli时 左边小滑块
    private val smallIndicatorRectF = RectF() // style == FakeAli时 左边小滑块背景
    // =======================  Interface  ============================
    var scrollListener:OnKingKongScrollListener?=null
    private var indicatorCreator: KIndicatorCreator? = null
    // ======================= Indicator Params ==========================
    //距离KingKongView顶部间距
    private var indicatorMarginTop = 0

    private var indicatorWidth = 20.dp
    private var indicatorHeight = 4.dp
    //小滑块宽度 == 正常情况的滑块宽度
    private val smallIndicatorWidth
        get() = if (mStyle == KingKongStyle.FAKE_ALI) indicatorThumbWidth else 0
    //style ==  Ali 时小指示器 离 右边指示器间距
    private var smallIndicatorHorizonGap = 3.dp
        get() = if (mStyle == KingKongStyle.FAKE_ALI) field else 0
        set(value) {
            field = value
        }
    // style ==  Ali 时小指示器 离 右边指示器总距离
    private val indicatorLeftX
        get() = smallIndicatorWidth + smallIndicatorHorizonGap
    // 大指示器 总宽度
    private val indicatorFullWidth
        get() = indicatorLeftX + indicatorWidth

    //内部小滑块宽度
    private var indicatorThumbWidth:Int = 0
        get() = if (field>0) field else (indicatorWidth / 3)
        set(value) {
            field = value
        }
    //滑块高度 默认 == 指示器高度
    private var indicatorThumbHeight = 0
        get() = if (field>0) field else indicatorHeight

    private var indicatorRadius = 10.dp
    private var indicatorBgColor = Color.GRAY
    private var indicatorThumbColor = Color.RED

    //KingKongView
    private var rv:RecyclerView?=null
    var mStyle:KingKongStyle? = null
        set(value) {
            field = value
            this.visibility = if (field!=null) VISIBLE else GONE
            postInvalidate()
        }

    constructor(context: Context,indicatorCreator: KIndicatorCreator?=null) : this(context = context, attrs = null) {
        this.indicatorCreator = indicatorCreator
    }

    init {
        visibility = GONE

        initView()

        initEvent()
    }

    private fun initEvent() {
        scrollListener = object :OnKingKongScrollListener{
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {}

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                if (rv == null) {
                    rv = recyclerView
                }
//                animThumb((rv?.scrollPercent?:0f)*(indicatorWidth-indicatorThumbWidth))
                //只保留小数点后两位
                animThumb(recyclerView.scrollPercent.format(2).toFloat())
            }
        }
    }

    private fun initView() {
        initPaint()
        if (indicatorMarginTop > 0) {
            margin(topMargin = indicatorMarginTop)
        }
    }

    private fun initPaint() {
        paint = Paint(Paint.ANTI_ALIAS_FLAG)
        paint?.apply {
            isDither = true
            style = Paint.Style.FILL
        }
    }

    fun setParams(
        indicatorWidth:Int=0,
        indicatorHeight:Int=0,
        indicatorRadius:Int = 0,
        indicatorBgColor:Int = 0,
        indicatorThumbColor:Int = 0,
        indicatorThumbWidth:Int=0,
        smallIndicatorHorizonGap:Int = 0,
        indicatorCreator: KIndicatorCreator?=null
    ) = apply {
        if (indicatorWidth > 0) {
            this.indicatorWidth = indicatorWidth
        }
        if (indicatorHeight > 0) {
            this.indicatorHeight = indicatorHeight
        }
        if (indicatorRadius > 0) {
            this.indicatorRadius = indicatorRadius
        }
        if (indicatorBgColor != 0) {
            this.indicatorBgColor = indicatorBgColor
        }
        if (indicatorThumbColor != 0) {
            this.indicatorThumbColor = indicatorThumbColor
        }
        if (indicatorThumbWidth > 0) {
            this.indicatorThumbWidth = indicatorThumbWidth
        }
        if (smallIndicatorHorizonGap > 0) {
            this.smallIndicatorHorizonGap = smallIndicatorHorizonGap
        }
        this.indicatorCreator = indicatorCreator
    }

    private var scrollPresent = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val thumbScrollX
        get() = scrollPresent * (indicatorWidth-indicatorThumbWidth)

//    private var thumbScrollX = 0f
//        set(value) {
//            field = value
//            invalidate()
//        }

    fun animThumb(x:Float){
//        ObjectAnimator.ofFloat(this,"thumbScrollX",x).apply {
//            duration = 0
//            start()
//        }
        ObjectAnimator.ofFloat(this,"scrollPresent",x).apply {
            duration = 0
            start()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(indicatorFullWidth,indicatorHeight)
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        if (indicatorCreator == null) {
            drawBg(canvas)
            drawThumb(canvas)
        }else{
            val scrollPercent = rv?.scrollPercent?:0f
            indicatorCreator?.draw(canvas!!,scrollPercent,indicatorWidth,indicatorHeight)
        }
    }

    private fun drawBg(canvas: Canvas?) {
        if (paint == null) {
            initPaint()
        }
        paint?.color = indicatorBgColor

        if (mStyle == KingKongStyle.FAKE_ALI) {
            smallIndicatorRectF.set(0f,0f, smallIndicatorWidth.toFloat(),indicatorHeight.toFloat())
            canvas?.drawRoundRect(smallIndicatorRectF,indicatorRadius.toFloat(),indicatorRadius.toFloat(),paint!!)
        }
        mIndicatorRectF.set(indicatorLeftX.toFloat(),0f,indicatorFullWidth.toFloat(),indicatorHeight.toFloat())
        canvas?.drawRoundRect(mIndicatorRectF,indicatorRadius.toFloat(),indicatorRadius.toFloat(),paint!!)
    }

    private fun drawThumb(canvas: Canvas?) {
        if (paint == null) {
            initPaint()
        }
        paint?.color = indicatorThumbColor
//        val left = (indicatorWidth - indicatorThumbWidth) / rvCanScrollDistance * rvScrollOffset
//        mThumbRectF.set(left.toFloat(),0f,(left+indicatorThumbWidth).toFloat(),if (indicatorThumbHeight<=0) indicatorHeight.toFloat() else indicatorThumbHeight.toFloat())

//        mThumbRectF.set(thumbScrollX,0f,thumbScrollX + indicatorThumbWidth.toFloat(),if (indicatorThumbHeight<=0) indicatorHeight.toFloat() else indicatorThumbHeight.toFloat())
//        canvas?.drawRoundRect(mThumbRectF,indicatorRadius.toFloat(),indicatorRadius.toFloat(),paint!!)

        if (mStyle == KingKongStyle.FAKE_ALI) {
            mSmallThumbRectF.set(smallIndicatorWidth*scrollPresent ,0f,smallIndicatorWidth.toFloat(),(indicatorThumbHeight).toFloat())
            canvas?.drawRoundRect(mSmallThumbRectF,indicatorRadius.toFloat(),indicatorRadius.toFloat(),paint!!)
        }
        if (mStyle == KingKongStyle.FAKE_ALI) {
            mThumbRectF.set(indicatorLeftX.toFloat() ,0f,indicatorLeftX + (smallIndicatorWidth*scrollPresent) ,(indicatorThumbHeight).toFloat())
        }else{
            mThumbRectF.set(thumbScrollX,0f,thumbScrollX + indicatorThumbWidth.toFloat(),indicatorThumbHeight.toFloat())
        }
        canvas?.drawRoundRect(mThumbRectF,indicatorRadius.toFloat(),indicatorRadius.toFloat(),paint!!)
    }

}